package com.test.server.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.*;
import com.test.message.Message;
import com.test.model.Connection;
import com.test.model.ConnectionManager;
import com.test.server.SyncFuture;
import com.test.server.service.ServerService;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * @Author mkl
 * @Date 2021/5/27 10:04
 * @Description
 */
@Slf4j
public class ServerServiceImpl implements ServerService {

    public static LoadingCache<String, SyncFuture<String>> futureCache = CacheBuilder.newBuilder()
            //设置缓存容器的初始容量为10
            .initialCapacity(100)
            // maximumSize 设置缓存大小
            .maximumSize(10000)
            //设置并发级别为20，并发级别是指可以同时写缓存的线程数
            .concurrencyLevel(20)
            // expireAfterWrite设置写缓存后8秒钟过期
            .expireAfterWrite(8, TimeUnit.SECONDS)
            //设置缓存的移除通知
            .removalListener(new RemovalListener<Object, Object>() {
                @Override
                public void onRemoval(RemovalNotification<Object, Object> notification) {
                    log.debug("LoadingCache: {} was removed, cause is {}", notification.getKey(), notification.getCause());
                }
            })
            //build方法中可以指定CacheLoader，在缓存不存在时通过CacheLoader的实现自动加载缓存
            .build(new CacheLoader<String, SyncFuture<String>>() {
                @Override
                public SyncFuture<String> load(String key) throws Exception {
                    // 当获取key的缓存不存在时，不需要自动添加
                    return null;
                }
            });

//    @Override
//    public boolean sendMsg(String text, String dataId, String serviceId) {
//
//        LOGGER.info("发送的内容：{}", text);
//
//        //TODO
//        //nettyClient.sendMsg(json);
//        return true;
//    }


//    @Override
//    public String sendSyncMsg(String text, String dataId, String serviceId) {
//
//        SyncFuture<String> syncFuture = new SyncFuture<String>();
//        // 放入缓存中
//        futureCache.put(dataId, syncFuture);
//
//        // 封装数据
//        JSONObject object = new JSONObject();
//        object.put("dataId", dataId);
//        object.put("text", text);
//
//        // 发送同步消息
//        String result = nettyClient.sendSyncMsg(object.toJSONString(), syncFuture);
//
//        return result;
//    }

    @Override
    public void ackSyncMsg(String msg, ChannelHandlerContext ctx) {
        log.info("ACK确认信息: {}", msg);
        Message message = JSONObject.parseObject(msg, Message.class);
        SyncFuture<String> syncFuture;
        Connection conn = ctx.channel().attr(ConnectionManager.connection).get();
        String imei = conn.getImei();
        syncFuture = futureCache.getIfPresent(imei + message.getHead() + message.getFunCode());
        // 如果不为null, 则通知返回
        if (syncFuture != null) {
            syncFuture.setResponse(msg);
            //主动释放
            futureCache.invalidate(imei + message.getHead() + message.getFunCode());
        }

    }

}
